<?php
/**
 * (ajax)
 */
namespace App\Admin\Ajax\Delivery;

use App\Func\UploadFile;
use App\Util\SerialNo;
use App\Models\Delivery\FBADelivery;
use App\Models\Delivery\FBADeliveryDetail;
use App\Models\Delivery\FBADeliveryLabels;
use App\Models\Delivery\FBADeliveryLogistics;
use App\Models\Delivery\FBADeliveryMarks;
use App\Models\Inventory\InventoryCn;
use App\Models\Inventory\Record;
use App\Models\Inventory\Placing;
use App\Models\Sys\Logs;
use Encore\Admin\Facades\Admin;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class FbaAjax {

    /**
     * 返回标签上传
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function backUploadLabels($id){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($id);
            if(!$model || !in_array($model->status,[2,3,4,5])){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $model->status = 1;
            $flag = $model->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 返回上传标签",$id);
                DB::commit();
                return response()->json(['status' => true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    /**
     * 标签上传完成
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadedLabels($id){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($id);
            if(!$model || $model->status != 1){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            if($model->labels->isEmpty()){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单无可下载标签！']);
            }
            $model->status = 2;
            $flag = $model->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('os-delivery',"发货单：{$model->delivery_no} 标签上传完成",$id);
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    /**
     * 箱唛上传完成
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function uploadedMarks($id){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($id);
            if(!$model || $model->status != 4){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            if($model->marks->isEmpty()){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单无可下载箱唛！']);
            }
            $model->status = 5;
            $flag = $model->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 箱唛上传完成",$id);
                DB::commit();
                return response()->json(['status' => true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    /**
     * 发货
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function ship($id){
        $model = FBADelivery::query()->findOrFail($id);
        if(!$model || $model->status != 5){
            return response()->json(['status' => false, 'message' => '发货单状态有误！']);
        }

        //DB::beginTransaction();
        //try{
            $userId = Admin::user()->id;
            $shipTotalUnit = 0;
            $totalUnitPrice = 0;
            $placingDetail = [];
            $flag1 = false;
            foreach($model->detail as $k => $detail){
                //库存差额数据回写
                $flag2 = $this->_shipRewrite($userId,$model->area_id,$detail->psku_id,$detail->apply_num,$detail->ship_num);
                if(!$flag2){
                    $flag1 = false;
                    break;
                }
                $flag1 = true;
                $shipTotalUnit += $detail->ship_num;
                $totalUnitPrice += $detail->unit_price * $detail->ship_num;

                //出库明细
                $placingDetail[$k]['order_no'] = $detail->delivery_no;
                $placingDetail[$k]['detail_id'] = $detail->id;
                $placingDetail[$k]['psku_id'] = $detail->psku_id;
                $placingDetail[$k]['placing_num'] = $detail->ship_num;
                $placingDetail[$k]['unit_price'] = $detail->unit_price;
            }
            if(!$flag1){
                //DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }
            $model->ex_status = 1;
            $model->ex_desc = 1;
            $model->status = 6;
            $model->delivered_at = date('Y-m-d H:i:s');
            $model->ship_total_unit = $shipTotalUnit; //产品总数
            $model->total_unit_price = $totalUnitPrice; //总成本
            $flag3 = $model->save();
            if(!$flag3){
                //DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }
            $placing = Placing::create([
                'placing_no' => SerialNo::getPlNo(),
                'placing_at' => date('Y-m-d'),
                'cuser_id' => $userId
            ]);
            $placing->detail()->createMany($placingDetail);
            if($placing){
                //日志
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 已发货",$id);
                //DB::commit();
                return response()->json(['status' => true,'message' => '操作成功！']);
            }else{
                //DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }
        //}catch (\Exception $e){
        //    DB::rollBack();
        //    report($e);
        //    return response()->json(['status' => false, 'message' => '系统异常！']);
        //}
    }

    /**
     * *发货*
     * 库存差额数据回写
     * @param $userId
     * @param $areaId
     * @param $pSkuId
     * @param $applyNum
     * @param $shipNum
     * @return bool
     */
    private function _shipRewrite($userId,$areaId,$pSkuId,$applyNum,$shipNum){

        $inventory = InventoryCn::query()
            ->where('area_id' , $areaId)
            ->where('psku_id' , $pSkuId)
            ->lockForUpdate()
            ->first();
        if(!$inventory){
            return false;
        }
        $inventory->reserve -= min($inventory->reserve,$applyNum);
        $inventory->instant += $applyNum - $shipNum;
        $flag1 = $inventory->save();
        if(!$flag1){
            return false;
        }
        $flag2 = Record::query()->create([
            'record_no' => SerialNo::getRcNo(),
            'psku_id' => $pSkuId,
            'area_id' => $areaId,
            'action_type' => 4,
            'record_type' => 2,
            'num' => -$shipNum,
            'user_id' => $userId,
        ]);
        if(!$flag2){
            return false;
        }
        return true;
    }

    //上传标签
    public function listUploadLabels($id){
        return view('delivery.fba.modal-labels',compact('id'));
    }

    public function doUploadLabels(UploadedFile $file,$param){
        if($file->isValid()){
            try{
                DB::beginTransaction();
                $model = FBADelivery::query()->findOrFail($param['id']);
                if(!$model || $model->status != 1){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '发货单状态有误！']);
                }
                $uploadFile = UploadFile::getInit();
                $path = $uploadFile->upload($file,'labels');
                if(!$path){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '操作失败！']);
                }
                $label = $model->labels()->create(['labels_name' => $param['labels_name'],'d_labels' => $path]);
                if(!$label){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '操作失败！']);
                }else{
                    Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 上传标签",$param['id']);
                    DB::commit();
                    return response()->json(['status' => true, 'message' => '操作成功！']);
                }
            }catch (\Exception $e){
                DB::rollBack();
                report($e);
                return response()->json(['status' => false, 'message' => '系统异常！']);
            }
        }else{
            return response()->json(['status' => false, 'message' => '无效文件！']);
        }
    }

    //备货
    public function listStartPreparing($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        $status = $delivery->status;
        if($delivery && $delivery->status == 2){
            try{
                DB::beginTransaction();
                $delivery->status = 3;
                $flag = $delivery->save();
                if(!$flag){
                    DB::rollBack();
                }else{
                    Logs::logs('fba-delivery',"发货单：{$delivery->delivery_no} 开始备货",$id);
                    DB::commit();
                }
            }catch (\Exception $e){
                DB::rollBack();
                report($e);
            }
        }
        return view('delivery.fba.modal-prepare',compact('id','delivery','status'));
    }

    public function doPrepare($param){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($param['id']);
            if(!$model || $model->status != 3){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $flag1 = false;
            foreach ($param['detail'] as $item){
                $detail = FBADeliveryDetail::query()->findOrFail($item['id']);
                $detail->ship_num += $item['ship_num'];
                if($detail->ship_num < 0)$detail->ship_num = 0;
                $flag2 = $detail->save();
                if(!$flag2){
                    $flag1 = false;
                    break;
                }
                $flag1 = true;
            }
            if(!$flag1){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 备货中",$param['id']);
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    public function listPreparing($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        $status = $delivery->status;
        return view('delivery.fba.modal-prepare',compact('id','delivery','status'));
    }

    //备货完成
    public function listPrepared($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        return view('delivery.fba.modal-prepared',compact('id','delivery'));
    }

    public function doPrepared($param){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($param['id']);
            if(!$model || $model->status != 3){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            if($param['total_box'] == 0){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '请填写发货箱数！']);
            }
            $model->total_box = $param['total_box'];
            $model->status = 4;
            $flag = $model->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 备货完成",$param['id']);
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    //上传箱唛
    public function listUploadMarks($id){
        return view('delivery.fba.modal-marks',compact('id'));
    }

    public function doUploadMarks(UploadedFile $file,$param){
        if($file->isValid()){
            try{
                DB::beginTransaction();
                $delivery = FBADelivery::query()->findOrFail($param['id']);
                if($delivery->status != 4){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '发货单状态有误！']);
                }
                $uploadFile = UploadFile::getInit();
                $path = $uploadFile->upload($file,'marks');
                if(!$path){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '操作失败！']);
                }
                $marks = $delivery->marks()->create(['marks_name' => $param['marks_name'],'d_marks' => $path]);
                if(!$marks){
                    DB::rollBack();
                    return response()->json(['status' => false, 'message' => '操作失败！']);
                }else{
                    Logs::logs('fba-delivery',"发货单：{$delivery->delivery_no} 上传箱唛",$delivery->id);
                    DB::commit();
                    return response()->json(['status' => true, 'message' => '操作成功！']);
                }
            }catch (\Exception $e){
                DB::rollBack();
                report($e);
                return response()->json(['status' => false, 'message' => '系统异常！']);
            }
        }else{
            return response()->json(['status' => true, 'message' => '无效文件！']);
        }
    }

    //更新物流
    public function listLogistics($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        return view('delivery.fba.modal-logistics',compact('id','delivery'));
    }

    public function doLogistics($param){
        try{
            DB::beginTransaction();
            $delivery = FBADelivery::query()->findOrFail($param['id']);
            if($delivery->status != 6){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $item = [
                'express_company_id' => $param['express_company_id'],
                'area_id' => $delivery->area_id,
                'express_channel_id' => $param['express_channel_id'],
                'tracking_no' => $param['tracking_no'],
                'total_weight' => $param['total_weight'],
                'shipping_fee' => $param['shipping_fee'],
                'other_fee' => $param['other_fee'],
            ];
            if($param['arrived_at']){
                $item['arrived_at'] = $param['arrived_at'];
            }
            $sl = FBADeliveryLogistics::query()->updateOrCreate(['delivery_no' => $delivery->delivery_no], $item);
            if(!$sl){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }
            $delivery->logistics_status = 2;
            if($sl->tracking_no){
                $delivery->track_ex_status = 2;//已录入
            }
            $flag = $delivery->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$delivery->delivery_no} 物流信息已更新",$delivery->id);
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    //EDIT
    /**
     * 删除标签
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function delLabels($id){
        try{
            DB::beginTransaction();
            list($deliveryId,$labelsId) = explode('-',$id);
            $delivery = FBADelivery::query()->findOrFail($deliveryId);
            if($delivery->status != 1){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $labels = FBADeliveryLabels::query()->findOrFail($labelsId);
            if($labels){
                $uploadFile = UploadFile::getInit();
                $flag1 = $uploadFile->delFile($labels->d_labels);
                $flag = $flag1 && $labels->delete();
            }else{
                $flag = true;
            }
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    /**
     * 删除箱唛
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function delMarks($id){
        try{
            DB::beginTransaction();
            list($deliveryId,$marksId) = explode('-',$id);
            $delivery = FBADelivery::query()->findOrFail($deliveryId);
            if($delivery->status > 4){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $marks = FBADeliveryMarks::query()->findOrFail($marksId);
            if($marks){
                $uploadFile = UploadFile::getInit();
                $flag1 = $uploadFile->delFile($marks->d_marks);
                $flag = $flag1 && $marks->delete();
            }else{
                $flag = true;
            }
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    //开始备货
    public function startPreparing($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        $status = $delivery->status;
        if($delivery && $delivery->status == 2){
            try{
                DB::beginTransaction();
                $delivery->status = 3;
                $flag = $delivery->save();
                if(!$flag){
                    DB::rollBack();
                }else{
                    Logs::logs('fba-delivery',"发货单：{$delivery->delivery_no} 开始备货",$id);
                    DB::commit();
                }
            }catch (\Exception $e){
                DB::rollBack();
                report($e);
            }
        }
        return view('delivery.fba-edit.modal-prepare',compact('id','delivery','status'));
    }

    public function preparing($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        $status = $delivery->status;
        return view('delivery.fba-edit.modal-prepare',compact('id','delivery','status'));
    }

    /**
     * 备货完成
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function prepared($id){
        try{
            DB::beginTransaction();
            $delivery = FBADelivery::query()->findOrFail($id);
            if($delivery->status != 3){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            if($delivery->total_box == 0){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '请填写发货箱数！']);
            }
            $delivery->status = 4;
            $flag = $delivery->save();
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                Logs::logs('fba-delivery',"发货单：{$delivery->delivery_no} 备货完成",$id);
                DB::commit();
                return response()->json(['status' =>true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }

    /**
     * 上传标签
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function uploadLabels($id){
        return view('delivery.fba-edit.modal-labels',compact('id'));
    }

    /**
     * 上传箱唛
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function uploadMarks($id){
        return view('delivery.fba-edit.modal-marks',compact('id'));
    }

    /**
     * 更新物流
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function logistics($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        return view('delivery.fba-edit.modal-logistics',compact('id','delivery'));
    }

    //SHOW
    /**
     * 查看物流信息
     * @param $id
     * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     */
    public function viewLogistics($id){
        $delivery = FBADelivery::query()->findOrFail($id);
        return view('delivery.fba-detail.modal-logistics',compact('delivery'));
    }

    /**
     * 删除发货单
     * @param $id
     * @return \Illuminate\Http\JsonResponse
     */
    public function fbaDel($id){
        try{
            DB::beginTransaction();
            $model = FBADelivery::query()->findOrFail($id);
            if(!$model || $model->status != 1){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '发货单状态有误！']);
            }
            $flag = false;
            foreach($model->detail as $detail){
                $inventory = InventoryCn::query()->where('area_id',$model->area_id)
                    ->where('psku_id',$detail->psku_id)
                    ->lockForUpdate()
                    ->first();
                if(!$inventory){
                    $flag = false;
                    break;
                }
                $inventory->reserve -= min($inventory->reserve,$detail->apply_num);
                $inventory->instant += $detail->apply_num;
                $flag1 = $inventory->save();
                if(!$flag1){
                    $flag = false;
                    break;
                }
                $flag = true;
            }
            if(!$flag){
                DB::rollBack();
                return response()->json(['status' => false, 'message' => '操作失败！']);
            }else{
                $model->delete();
                Logs::logs('fba-delivery',"发货单：{$model->delivery_no} 已删除(返还库存数量)",$id);
                DB::commit();
                return response()->json(['status' => true, 'message' => '操作成功！']);
            }
        }catch (\Exception $e){
            DB::rollBack();
            report($e);
            return response()->json(['status' => false, 'message' => '系统异常！']);
        }
    }
}
